#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <incoming.h>
#include <memcheck.h>
#include <listener.h>
#include <config.h>
#include <log.h>
#include <Singleton.h>
#include <http_decoder.h>
#include <stat_manager.h>
#include <stdlib.h>

HTTP_SVR_NS_BEGIN

CIncoming::CIncoming (void) :
_pollerunit (NULL),
_listener (NULL),
_timerunit (NULL),
_webtimerlist (NULL),
_helpertimerlist (NULL),
_epwaittimeout (1000)
{
    
}

CIncoming::~CIncoming (void) 
{
    DELETE (_timerunit);
    
    DELETE (_listener);

    DELETE (_pollerunit);

    CStatManager::Destroy ();
}

CIncoming* CIncoming::Instance (void)
{
    return CSingleton<CIncoming>::Instance ();
}

void CIncoming::Destroy (void)
{
    return CSingleton<CIncoming>::Destroy ();
}

int CIncoming::open (void)
{ 

    
    //create poller unit
    NEW (CPollerUnit(TGlobal::_maxpoller), _pollerunit);

    if (NULL == _pollerunit)
    {
        log_boot ("create CPollerUnit object failed.");

        return -1;
    }

    //create listener
    NEW (CListener(TGlobal::_addr, TGlobal::_port, MAX_ACCEPT_COUNT), _listener);

    if (NULL == _listener)
    {
        log_boot ("create CListener object failed.");

        return -1;
    }

    //create CTimerUnit object
    NEW (CTimerUnit(), _timerunit);

    if (NULL == _timerunit)
    {
        log_boot ("create CTimerUnit object failed.");

        return -1;
    }

    //create web timer list
    _webtimerlist = _timerunit->GetTimerList (TGlobal::_webtimeout);

    if (NULL == _webtimerlist)
    {
        log_boot ("create web CTimerList object failed.");
        return -1;
    }

    _helpertimerlist = _timerunit->GetTimerList (TGlobal::_helpertimeout);

    if (NULL == _helpertimerlist)
    {
        log_boot ("create helper CTimerList object failed.");

        return -1;
    }

    //init http error msg array
    CHttpDecoder::init ();
           
    //init stat manager
    if (CStatManager::Instance()->open() < 0)
    {
        log_boot ("init CStatManager instance failed.");

        return -1;
    }

    //init poller unit
    if(_pollerunit->InitializePollerUnit() < 0)
    {
        log_boot ("poller unit init failed.");
        
        return -1;
    }
    
    //attach decoder unit
    if (_listener->Attach (_pollerunit, _webtimerlist, _helpertimerlist, TGlobal::_backlog) < 0)
    {
        log_boot ("invoke CListener::Attach() failed.");

        return -1;
    }
    
    _compressUnit=compress_unit::Instance();
    if(_compressUnit==NULL)
    {
        return -1;
    }
   log_debug("thread count %d",TGlobal::_gzip_thread_count );
    if(_compressUnit->Set_gzip_thread_num(TGlobal::_gzip_thread_count )<0)
    {
        return -1;
    }
    return 0;

}

void CIncoming::ProcessWebOut()
{
    vector<gzip_task> webout_vec;
    compress_unit::Instance()->Out_queue_task(webout_vec);
    int vec_len=webout_vec.size();
    for(int i=0;i<vec_len;i++)
    {
        int client_fd=webout_vec[i]._gzip_obj->get_owner()->get_web_unit()->get_netfd();

        TGlobal::_debug_mem[client_fd].fd=0;
        TGlobal::_debug_mem[client_fd].obj_p=0;

        webout_vec[i]._gzip_obj->set_inqueue_flag(0);
        if(webout_vec[i]._gzip_obj->get_terminate_flag()==1)
        {
            webout_vec[i]._gzip_obj->terminate_delayed();    
        }
        else
        {
            webout_vec[i]._gzip_obj->flush_cgi_result();
        }
    }
    compress_unit::Instance()->Process_waiting_task();
}


int CIncoming::run (void)
{
    while(!(*(TGlobal::_module_close)))
    {
        _pollerunit->WaitPollerEvents (100);
        _pollerunit->ProcessPollerEvents ();
        ProcessWebOut();
    }

    return 0;
}

HTTP_SVR_NS_END

